#include "ArduinoPlatform.h"

BarcodeItem ITEM;
LiquidCrystal LCD(7, 6, 5, 4, 3, 2);
analogKey KeyPad;
Melody melody(11);

boolean operatorFirstKeyPress = false;
boolean barcodeFirstKeyPress = false;
boolean defectFirstKeyPress = false;

volatile CurrentMode currentMode;
volatile boolean readFunc = false;
volatile boolean do_loop = true;
unsigned long last_time;

uint8_t bit0, bit1, bit2;

void ISR_Function_Key()
{
	readFunc = true;
	do_loop = false;
	currentMode = ModeNone;
}

void setup()
{
	//EEPROM_readAnything(ee_devices_id,DeviceID);
	EEPROM_readAnything(ee_ready,WaitForSend);
	
	LCD.begin(20, 4);
	KeyPad.init(4);
	
	LCD.setCursor(0,0);
	LCD.print("STATION ID:");
	LCD.print(DeviceID);
	LCD.setCursor(0,1);
	LCD.print(STR_INIT);
	
	for(int i = 0; i<512; i++)
	EEPROM.write(i, 0);
	for(int i = 14; i < 19; i++)
	pinMode(i, INPUT);
	for(int i = 8; i < 11; i++)
	pinMode(i, INPUT);
	
	PCintPort::attachInterrupt(8, &ISR_Function_Key, FALLING);
	Serial.begin(9600);

	currentMode = ModeWelcome;
	melody.PlayStartup();
}

void loop()
{
	bit0 = !digitalRead(9);
	bit1 = !digitalRead(10);
	bit2 = !digitalRead(11);
	
	if(readFunc)
	{
		unsigned long this_time = millis();
		if(this_time - last_time > 200)
		{
			readFunc = false;
			last_time = this_time;

			if(bit0 == 0 && bit1 == 0 && bit2 == 0)
			{
				currentMode = ModeWelcome;
				
			}
			else if(bit0 == 0 && bit1 == 0 && bit2 == 1)
			{
				currentMode = ModeOperatorId;
				
			}
			else if(bit0 == 0 && bit1 == 1 && bit2 == 0)
			{
				currentMode = ModeBarcode;
				
			}
			else if(bit0 == 0 && bit1 == 1 && bit2 == 1)
			{
				currentMode = ModeDefect;
				
			}
			else if(bit0 == 1 && bit1 == 0 && bit2 == 0)
			{
				currentMode = ModeSummary;
				
			}
			else if(bit0 == 1 && bit1 == 0 && bit2 == 1)
			{
				currentMode = ModeSubmit;
				
			}
			else if(bit0 == 1 && bit1 == 1 && bit2 == 0)
			{
				currentMode = ModeNone;
			}
			else if(bit0 == 1 && bit1 == 1 && bit2 == 1)
			{
				currentMode = ModeNone;
			}
			else
			{
				currentMode = ModeNone;
			}
			//Serial.print("=>Interrupt triggered.");
			//digitalWrite(13, HIGH);
			//delay(50);
			//digitalWrite(13, LOW);
		}
	}
	
	if(currentMode != ModeNone)
	{
		//Serial.print("<=Mode triggered.");
		switch(currentMode)
		{
			case ModeWelcome:
			//Serial.println("[welcome]");
			currentMode = ModeNone;
			WelcomeFunc();
			break;
			case ModeOperatorId:
			//Serial.println("[operator]");
			currentMode = ModeNone;
			OperatorFunc();
			break;
			case ModeBarcode:
			//Serial.println("[barcode]");
			currentMode = ModeNone;
			BarcodeFunc();
			break;
			case ModeDefect:
			//Serial.println("[defect]");
			currentMode = ModeNone;
			DefectFunc();
			break;
			case ModeSummary:
			//Serial.println("[summary]");
			currentMode = ModeNone;
			SummaryFunc();
			break;
			case ModeSubmit:
			//Serial.println("[submit]");
			currentMode = ModeNone;
			SubmitFunc();
			break;
			default:
			//Serial.println("[default]");
			currentMode = ModeNone;
			DefaultFunc();
			break;
		}
	}
	delay(50);
}

void WelcomeFunc()
{
	LCD.clear();
	//LCD.setCursor(0, 0);
	//LCD.print("WELCOME...");
	LCD.setCursor(17, 3);
	LCD.print(memoryFree());
	
	operatorFirstKeyPress = false;
	barcodeFirstKeyPress = false;
	defectFirstKeyPress = false;
}
void OperatorFunc()
{
	char operator_id[6] = "     ";
	char c[2];
	int c_col = 0;
	
	if(strlen(ITEM.GetQcId()) < 5 || operatorFirstKeyPress == true)
	{
		operatorFirstKeyPress = false;
		int input;
		do_loop = true;
		
		LCD.clear();
		LCD.setCursor(0, 0);
		LCD.print("ENTER QC ID:");
		
		while(do_loop)
		{
			input = KeyPad.readKeyUp(0, 0);
			if(input > -1 && input < 10 && c_col < 5)
			{
				LCD.setCursor(c_col, 1);
				LCD.print(input);
				itoa(input, c, 10);
				operator_id[c_col] = c[0];
				c_col++;
				operator_id[c_col] = '\0';
				//Serial.println(operator_id);
			}
			else if(input == 11 && c_col > 0)
			{
				clearChar(operator_id);
				LCD.clearLine(1);
				c_col = 0;
			}
			else if(input == 11 && c_col == 0)
			{
				break;
			}
			else if(input == 12 && c_col == 5)
			{
				ITEM.SetQcId(operator_id);
				break;
			}
			delay(50);
		}
		
		if(do_loop)
		{
			DisplayOperator(ITEM.GetQcId());
			operatorFirstKeyPress = true;
		}
	}
	else if(strlen(ITEM.GetQcId()) > 0)
	{
		DisplayOperator(ITEM.GetQcId());
		operatorFirstKeyPress = true;
	}
}
void BarcodeFunc()
{
	char barcode[10] = "         ";
	char c[2];
	int c_col = 0;
	
	if(strlen(ITEM.GetBarcode()) < 9 || barcodeFirstKeyPress == true)
	{
		barcodeFirstKeyPress = false;
		int input;
		do_loop = true;
		bool barcode_ok = false;
		
		LCD.clear();
		LCD.setCursor(0, 0);
		LCD.print("ENTER BARCODE:");
		
		while(do_loop)
		{
			input = KeyPad.readKeyUp(0, 0);
			if(input > -1 && input < 10 && c_col < 9)
			{
				LCD.setCursor(c_col, 1);
				LCD.print(input);
				itoa(input, c, 10);
				barcode[c_col] = c[0];
				c_col++;
				barcode[c_col] = '\0';
			}
			else if(input == 11 && c_col > 0)
			{
				clearChar(barcode);
				LCD.clearLine(1);
				c_col = 0;
			}
			else if(input == 11 && c_col == 0)
			{
				ITEM.SetHeType(-1);
				ITEM.SetBarcode("");
				barcode_ok = false;
				break;
			}
			else if(input == 12 && c_col == 9)
			{
				ITEM.SetBarcode(barcode);
				barcode_ok = true;
				break;
			}
			delay(50);
		}
		
		if(barcode_ok)
		{
			//do_loop = true;
			uint8_t h = -1;
			LCD.clearLine(2);
			LCD.print("ENTER TYPE: 1A, 2B");
			
			while(do_loop)
			{
				input = KeyPad.readKeyUp(0, 0);
				if(input == 1)
				{
					h = 1;
					LCD.setCursor(0, 3);
					LCD.print("A");
				}
				else if(input == 2)
				{
					h = 2;
					LCD.setCursor(0, 3);
					LCD.print("B");
				}
				else if(input == 11 && h != -1)
				{
					h = -1;
					LCD.setCursor(0, 3);
					LCD.print(" ");
				}
				else if(input == 11 && h == -1)
				{
					ITEM.SetHeType(-1);
					ITEM.SetBarcode("");
					break;
				}
				else if(input == 12 && h != -1)
				{
					ITEM.SetHeType(h);
					break;
				}
			}
		}
		
		if(strlen(ITEM.GetBarcode()) > 0 && ITEM.GetHeType() > -1 && barcode_ok && do_loop)
		{
			LCD.clear();
			LCD.setCursor(0, 0);
			LCD.print(ITEM.GetBarcode());
			LCD.print("-");
			char c = '-';
			ITEM.GetHeTypeChar(c);
			LCD.print(c);
			barcodeFirstKeyPress = true;
		}
		
	}
	else if(strlen(ITEM.GetBarcode()) == 9 && barcodeFirstKeyPress == false)
	{
		LCD.clear();
		LCD.setCursor(0, 0);
		LCD.print(ITEM.GetBarcode());
		LCD.print("-");
		char c = '-';
		ITEM.GetHeTypeChar(c);
		LCD.print(c);
		barcodeFirstKeyPress = true;
	}
	else if(strlen(ITEM.GetBarcode()) == 0 && barcodeFirstKeyPress == false)
	{
		LCD.clear();
		LCD.setCursor(0, 0);
		LCD.print("NO BARCODE!");
		barcodeFirstKeyPress = true;
	}
}
void DefectFunc()
{

}
void SummaryFunc()
{
	LCD.clear();
	LCD.print("QC ID:"); LCD.print(ITEM.GetQcId());
	LCD.setCursor(0, 1);
	LCD.print(ITEM.GetBarcode());
	LCD.print("-");
	char c;
	ITEM.GetHeTypeChar(c);
	LCD.print(c);
	LCD.setCursor(0, 2);
	LCD.print("GOOD QTY:");
	LCD.print(ITEM.GetGoodQty());
	LCD.setCursor(0, 3);
	LCD.print("DEF. QTY:");
	LCD.print(ITEM.GetTotalDefectQty());
}
void SubmitFunc()
{
	LCD.clear();
	LCD.print("SUBMITTING DATA");
	LCD.setCursor(0, 1);
	LCD.print("PLEASE WAIT...");
	delay(1000);
	LCD.clearLine(0);
	LCD.print("SUBMIT DATA");
	LCD.clearLine(1);
	LCD.print("COMPLETED.");
	ITEM.Reset();
}
void DefaultFunc()
{
	WelcomeFunc();
}

void DisplayOperator(char c[])
{
	if(strlen(c)> 0)
	{
		char cmd[14] = "GET|NAM|";
		
		cmd[8] = c[0];
		cmd[9] = c[1];
		cmd[10] = c[2];
		cmd[11] = c[3];
		cmd[12] = c[4];
		cmd[13] = '\0';
		
		char cmd2[31];
		
		while(Serial.available())
		Serial.flush();
		
		//Serial.println(cmd2);
	}
	else
	{
		LCD.clear();
		LCD.print("NO QC ID!");
	}
}

void DisplayDefect(uint8_t defect_id)
{
	LCD.clear();
	LCD.setCursor(0, 0);
	LCD.print("TOTAL:");
	LCD.print(ITEM.GetTotalDefectQty());
	if(defect_id == -1)
	{
		LCD.setCursor(0, 1);
		LCD.print("DEF.ID:");
		LCD.setCursor(0, 2);
		LCD.print("DEF.QTY:");
	}
	else
	{
		LCD.setCursor(0, 1);
		LCD.print("DEF.ID:");
		LCD.print(defect_id);
		LCD.setCursor(0, 2);
		LCD.print("DEF.QTY:");
		LCD.print(ITEM.GetDefectQty(defect_id));
	}
}

int8_t serial_ch_index = 0;
char serialString[31];
char *serialCmd[10];
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////

void serialEvent()
{
	pinMode(13,OUTPUT);
	digitalWrite(13,1);
	
	uint8_t src = 0x00;
	uint8_t func = 0x00;
	uint8_t rw = 0x00;
	
	//////////////////////////////////////////////////////////////////////////
	while(Serial.available() >= 5)
	{
		LCD.clear();
		while(Serial.read() != STX);
		
		int id = Serial.read();

		if(id == DeviceID)
		{
			Serial.readBytesUntil('$',serialString,30);
			src = (byte)serialString[0];
			func = (byte)serialString[1];
			rw=(byte)serialString[2];
			
			LCD.print("SRC:"); LCD.print(src);
			LCD.print("FUNC:"); LCD.print(func);
			LCD.print("RW:");LCD.print(rw);
			
			//SendACK(MASTER, DeviceID);
			
			if(func == FUNC_BARCODE)
			{
				SendBarcode(src, DeviceID, 0x28C9,0x1E85E0E9, HE_B, 0x017A, 0x01);
				melody.PlaySuccess();
			}
			else if(func == FUNC_KEEP_ALIVE)
			{
				SendACK(src, DeviceID);
			}
			else if(func == FUNC_REQ_QC && rw== FUNC_WRITE)
			{
				LCD.setCursor(0, 3);
				LCD.print("GET OPERATOR");
			}
			else
			{
				while(Serial.read() != EOT);
			}
		}
		else
		{
			while(Serial.read() != EOT);
		}
	}
	//////////////////////////////////////////////////////////////////////////
	
	//while (Serial.available())
	//{
		//char inChar = (char)Serial.read();
		//
		//if(inChar == '$') //$
		//{
			//serialString[serial_ch_index] = '$';
			//serial_ch_index++;
			//serialString[serial_ch_index] = '\0';
			//
			//serial_ch_index = 0;
			//
			////Serial.print(serialString);
			//
			//ProcessSerialString();
			//
			//serialString[0] = '\0';
		//}
		//else if(inChar != '\r' && inChar != '\n') // \r\n
		//{
			//serialString[serial_ch_index] = inChar;
			//serial_ch_index++;
		//}
	//}
	digitalWrite(13,0);
}

void ProcessSerialString()
{
	LCD.clear();
	
	char str[31] = "";
	char* seq_str_bak="";
	
	char* seq_str;
	//char* split_str;
	
	strncpy(str,serialString,strlen(serialString));
	
	seq_str = strtok (str,":$");
	while (seq_str != NULL)
	{
		strncpy(seq_str_bak,seq_str,strlen(seq_str));

		LCD.setCursor(0,0);
		LCD.print(seq_str);
		
		//////////////////////////////////////////////////////////////////////////
		int8_t i = 0;

		serialCmd[i] = strtok(seq_str_bak, "|");
		while( serialCmd[i] != NULL  )
		{
			serialCmd[++i] = strtok( NULL, "|");
		}

		if(atoi(serialCmd[0])==DeviceID)
		{
			for (int8_t j = 0; j < i-1; j++ )
			{
				LCD.setCursor(j,1);
				LCD.print(serialCmd[j]);
			}
		}
		//////////////////////////////////////////////////////////////////////////
		
		seq_str = strtok(NULL, ":$");
	}
	
	LCD.setCursor(17,3);
	LCD.print(memoryFree());

	////GET or SET
	//if(serialString[0] == 'S' && serialString[1] == 'E' && serialString[2] == 'T')
	//{
		//set = true;
		//get = false;
	//}
	//else if(serialString[0] == 'G' && serialString[1] == 'E' && serialString[2] == 'T')
	//{
		//set = false;
		//get = true;
	//}
	////Sub command
	//if(serialString[4] == 'N' && serialString[5] == 'A' && serialString[6] == 'M') //OPERATOR NAME
	//{
		//cmd='n';
	//}
	/////////////////////////////////////////////////////////////
	////Content
	//strncpy(str,(serialString + 8), strlen(serialString) - 8);
	//
	//int8_t x=0;
	//char * pch;
	//pch = strtok (str,"|$");
	//while (pch != NULL)
	//{
		//para[x]=pch;
		//x++;
		//pch = strtok (NULL, "|$");
	//}
	//
	////////////////////////////////////////////////////////////
	//if(set)
	//{
		//if(cmd == 'n') // operator name
		//{
			//LCD.clear();
			//LCD.setCursor(0, 0);
			//LCD.print("QC ID:");
			//LCD.print(para[0]);
			//LCD.setCursor(0, 1);
			//LCD.print("NAME:");
			//LCD.print(para[1]);
		//}
	//}
	//else if(get)
	//{
		//
	//}

	//int8_t len = strlen(serialString);
	//for(int8_t x=0;x<len;x++)
	//serialString[x]='\0';
}

